#pragma once

#include "ogl/math/Transform.h"
#include "ogl/math/Camera.h"

namespace Ogl {


    namespace Phong
    {

        const int maxDirNum = 8;
        const int maxPointNum = 8;
        const int maxSpotNum = 8;

        using namespace glm;

        struct PassData3d
        {
            glm::mat4 proj;
            glm::mat4 view;
            glm::mat4 projView;
            glm::vec3 camPos;
            float pad=0.f;

            PassData3d() = default;
            PassData3d(const Ogl::Math::Camera& camera)
            {
                camPos = camera.position;
                proj = camera.GetProjection();
                view = camera.GetViewMatrix();
                projView = proj * view;

            }


        };
        struct ObjData3d
        {
            glm::mat4 world;
            glm::mat4 worldInv;
            glm::mat4 worldInvTranspose;
            ObjData3d() = default;
            ObjData3d(const Ogl::Math::Transform& transform)
            {
                world = transform.GetWorld();
                worldInv = glm::inverse(world);
                worldInvTranspose = glm::transpose(worldInv);
            }
        };

        struct Material
        {
            vec4 ambient = { 0.5f,0.5f,0.5f,1.0f };
            vec4 diffuse = { 1.0f,1.0f,1.0f,1.0f };
            vec4 specular = { 0.5f,0.5f,0.5f, 32.0f };

        };

        struct DirLight
        {
            vec3 ambient = vec4(0.5f, 0.5f, 0.5f, 1.0f);
            float pad0;

            vec3 diffuse = vec4(0.5f, 0.5f, 0.5f, 1.0f);
            float pad1;

            vec3 specular = vec4(0.5f, 0.5f, 0.5f, 1.0f);
            float pad2;

            vec3 direction = vec3(0.0f, -1.0f, 0.f);
            float pad;


        };

        struct PointLight
        {
            vec3 ambient = vec4(0.5f, 0.5f, 0.5f, 1.0f);
            float pad0;

            vec3 diffuse = vec4(0.5f, 0.5f, 0.5f, 1.0f);
            float pad1;

            vec3 specular = vec4(0.5f, 0.5f, 0.5f, 1.0f);
            float pad2;
            vec3 position;
            float pad;

            float constant = 1.0f;
            float linear = 0.09;
            float quadratic = 0.032;
            float pad4;

        };

        struct SpotLight
        {
            vec3 ambient = vec4(0.5f, 0.5f, 0.5f, 1.0f);
            float pad0;

            vec3 diffuse = vec4(0.5f, 0.5f, 0.5f, 1.0f);
            float pad1;

            vec3 specular = vec4(0.5f, 0.5f, 0.5f, 1.0f);
            float pad2;


            vec3 position = vec3(0.0f, 2.0f, 0.f);
            float cutOff = glm::cos(glm::radians(12.5f));
            vec3 direction = vec3(0.f, -1.0f, 0.0f);
            float outerCutOff = glm::cos(glm::radians(15.0f));

            float constant = 1.0f;
            float linear = 0.09;
            float quadratic = 0.032;
            float pad;
        };


        struct LightEffect {

            DirLight dirlights[maxDirNum];
            PointLight pointLights[maxPointNum];
            SpotLight spotLights[maxSpotNum];

            int numDirlights = 0;
            int numPoints = 0;
            int numSpotLights = 0;
            int pad;

        };

    };
};